﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace BlenderLink
{
    public class Class1
    {
        public static TcpListener tcpListener;
        public static TcpClient tcpClient;
        public static NetworkStream tcpStream;
        public static ASCIIEncoding encoder = new ASCIIEncoding();

        public enum Command { CUBE, ELLIPSOID, CONE, CYLINDER, PYRAMID, CURVE_APPEND, CURVE_ACTIVATE, CURVE_DEACTIVATE, ROOF, ERASE, COLOR, HANDS, TUTORIAL_CUBE, TRANSLATE_SCENE, ROTATE_SCENE, ZOOM_SCENE }

        static void Main(string[] args)
        {
            //OPEN BLENDER
            Debug.WriteLine("opening Blender...");
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "C:\\Program Files\\Blender Foundation\\Blender\\blender.exe";
            //startInfo.Arguments = "-p 600 -400 700 650 --python \"C:\\Users\\Tom Piot\\Documents\\Eclipse Juno Workspace\\BlenderLink\\blenderlink2.py\"";
            startInfo.Arguments = "-p 700 0 1200 1200 --python \"C:\\Users\\Tom Piot\\Documenten\\Eclipse Juno Mobile Workspace\\BlenderLink\\blenderlink2.py\"";
            Process.Start(startInfo);

            //OPEN COMMUNICATION SOCKET
            tcpListener = new TcpListener(IPAddress.Any, 3000);
            tcpListener.Start();
            tcpClient = tcpListener.AcceptTcpClient(); //this blocks until a client connects
            tcpStream = tcpClient.GetStream();

            //START TESTING COMMANDS
            Random randomGenerator = new Random();

            float l = (float)((randomGenerator.NextDouble() - 1) * randomGenerator.Next(6));
            float r = (float)(l + 1 + randomGenerator.Next(2));
            float b = (float)((randomGenerator.NextDouble() - 1) * randomGenerator.Next(6));
            float t = (float)(b + 1 + randomGenerator.Next(2));
            float n = (float)((randomGenerator.NextDouble() - 1) * randomGenerator.Next(6));
            float f = (float)(n + 1 + randomGenerator.Next(2));
            float xe = (float)(-5 + randomGenerator.Next(11));
            float ye = (float)(-5 + randomGenerator.Next(11));
            float ze = (float)(-5 + randomGenerator.Next(11));
            float ra = (float)(1 + randomGenerator.Next(3));

            sendMessage("CURVE_ACTIVATE -2 -2 0 ");
            sendMessage("CURVE_APPEND -2 0 1 ");
            sendMessage("CURVE_APPEND -2 2 2 ");
            sendMessage("CURVE_APPEND 0 2 1 ");
            sendMessage("CURVE_APPEND 2 2 0 ");
            sendMessage(buildMessage(Command.ELLIPSOID, new float[] { 0, -3, 0, 1, 2, 1, 1 }));
            //sendMessage(buildMessage(Command.ELLIPSOID, new float[] { 0, 4, 0, 2, 1, 1, 2 }));
            //sendMessage(buildMessage(Command.ELLIPSOID, new float[] { 2, -2, 0, 0.5f, 1, 1, 1 }));
            sendMessage("CUBE 1 -1 -1 -1 1 1");
            
            Thread.Sleep(10000);

            for (int k = 0; k < 50; k++)
            {
                
                float x = (float)((randomGenerator.NextDouble() - 0.5) / 10);
                float y = (float)((randomGenerator.NextDouble() - 0.5) / 10);
                float z = (float)((randomGenerator.NextDouble() - 0.5) / 10);
                for (int i = 0; i < 50; i++)
                {
                    sendMessage(buildMessage(Command.TRANSLATE_SCENE, new float[] { 0, 0.02f, 0 }));
                    Thread.Sleep(20);
                }

                Thread.Sleep(5000);

                float angle = (float)(-3.1415/100);
                for (int i = 0; i < 50; i++)
                {
                    
                    sendMessage(buildMessage(Command.ROTATE_SCENE, new float[] { angle }));
                    Thread.Sleep(20);
                }

                Thread.Sleep(5000);
                //float zoomFactor = (float)(20 + randomGenerator.Next(180));
                //sendMessage(buildMessage(Command.ZOOM_SCENE, new float[] { zoomFactor }));
            }
            

            Thread.Sleep(100000);


            
        }

        //Sends a message to Blender
        public static void sendMessage(String message)
        {
            Debug.WriteLine("Sending this message to client: " + message);
            byte[] buffer = encoder.GetBytes(message);
            tcpStream.Write(buffer, 0, buffer.Length);
            tcpStream.Flush();
        }


        //Builds an appropiate message from the given data
        public static String buildMessage(Command Command, float[] data)
        {
            String message = Command.ToString() + " ";

            foreach (float f in data)
            {
                message += f.ToString("0.0000");
                message += " ";
            }

            return message.Replace(",", ".");
        }
    }
}
